
package adoc;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 *
 * @author ILikePancakes
 */
public class Zip {
    private ZipInputStream inputStream;
    private ZipOutputStream outputStream;
    private ZipEntry entry;
    private byte[] buffer;
    private String mode;
    private String zipName;
    private int UID;

    public Zip(String zipName, String mode, int UID) throws FileNotFoundException, RuntimeException {
        this.UID = UID;
        this.zipName = zipName;
        if (!mode.matches("r||w")) throw new RuntimeException("Wrong opening mode specified: use 'r' or 'w'");
        this.mode = mode;
        buffer = new byte[1024];
        if (mode.equals("w")) {
            outputStream = new ZipOutputStream(new FileOutputStream(zipName));
        }
    }

    public Zip(String zipName, String mode) throws FileNotFoundException, RuntimeException { this(zipName, mode, 0); }

    public long getSize() {
        return new File(zipName).length();
    }

    public void addFile(String filename, String zipfilename) throws FileNotFoundException, IOException {
        this.addFile(new File(filename), zipfilename);
    }

    public void addFile(File file, String zipfilename) throws FileNotFoundException, IOException {
        if (mode.equals("w")) {
            FileInputStream input = new FileInputStream(file);
            outputStream.putNextEntry(new ZipEntry(zipfilename.replace('\\', '/')));

            int length;
            while ((length = input.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }

            outputStream.closeEntry();
            input.close();
        } else
            throw new IOException("Zip file not opened for writing");
    }

    public void make() throws IOException {
        if (outputStream != null) outputStream.close();
    }

    public boolean isValid() {
        try {
            new ZipFile(zipName);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public ArrayList<String> extract() throws IOException, ZipException {
        inputStream = new ZipInputStream(new FileInputStream(zipName));
        ArrayList<String> entryNames = new ArrayList();
        entry = inputStream.getNextEntry();
        while (entry != null) {
            String entryName = entry.getName();
            if (entryName.replace('\\', '/').endsWith("/")) {
                inputStream.closeEntry();
                entry = inputStream.getNextEntry();
                continue;
            }
            entryNames.add(entryName.replace('\\', '/'));
            int n;
            FileOutputStream fileoutputstream;
            File newFile = new File(entryName);
            String directory = newFile.getParent();
            if(directory == null)
            {
                if(newFile.isDirectory())
                break;
            }
            File file = AdocUtilities.createTempFile(entryName, UID);
            //File file = AdocUtilities.createNewFile(AdocUtilities.getWorkingPath(UID), entryName);
            fileoutputstream = new FileOutputStream(file);

            while ((n = inputStream.read(buffer, 0, 1024)) > -1)
                fileoutputstream.write(buffer, 0, n);

            fileoutputstream.close();

            inputStream.closeEntry();
            entry = inputStream.getNextEntry();
        }
        inputStream.close();
        return entryNames;
    }
}
